﻿using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;

namespace Storm.TextEditor.Core.Splitting
{
	[ToolboxItem(false)]
	public class SplitViewChildControl : Widget
	{
		#region Fields

		private SplitViewThumbControl leftThumb = null;
		private SplitViewThumbControl topThumb = null;

		private ScrollBars   scrollBars = ScrollBars.None;
		protected DevExpress.XtraEditors.HScrollBar hScroll    = null;
        protected DevExpress.XtraEditors.VScrollBar vScroll = null;

		private Panel         filler           = null;
		private Container     components       = null;
		private WeakReference controlReference = null;

		private bool hasThumbs = false;

		#endregion

		#region Properties

		/// <summary>
		/// Gets or sets the left SplitViewThumbControl of the SplitViewChildControl.
		/// </summary>
		public SplitViewThumbControl LeftThumb
		{
			get { return leftThumb; }
			set { leftThumb = value; }
		}

		/// <summary>
		/// Gets or sets the top SplitViewThumbControl of the SplitViewChildControl.
		/// </summary>
		public SplitViewThumbControl TopThumb
		{
			get { return topThumb; }
			set { topThumb = value; }
		}

		/// <summary>
		/// Gets the area of the SplitViewChildControl client as a Rectangle.
		/// </summary>
		public Rectangle ClientArea
		{
			get
			{
				Rectangle r = this.ClientRectangle;

				r.Width -= vScroll.Width;
				r.Height -= hScroll.Height;

				return r;
			}
		}

		/// <summary>
		/// Gets or sets whether the left SplitViewThumbControl is visible.
		/// </summary>
		public bool LeftThumbVisible
		{
			get { return this.LeftThumb.Visible; }
			set
			{
				this.LeftThumb.Visible = value;
				this.DoResize();
			}
		}

		/// <summary>
		/// Gets or sets whether the top SplitViewThumbControl is visible.
		/// </summary>
		public bool TopThumbVisible
		{
			get { return this.TopThumb.Visible; }
			set
			{
				this.TopThumb.Visible = value;
				this.DoResize();
			}
		}

		/// <summary>
		/// Gets the visible height of the SplitViewChildControl client.
		/// </summary>
		public int VisibleClientHeight
		{
			get
			{
				if (hScroll.Visible == true)
					return this.ClientHeight - hScroll.Height;
				else
					return this.ClientHeight;
			}
		}

		/// <summary>
		/// Gets the visible width of the SplitViewChildControl client.
		/// </summary>
		public int VisibleClientWidth
		{
			get
			{
				if (hScroll.Visible == true)
					return this.ClientWidth - vScroll.Width;
				else
					return this.ClientWidth;
			}
		}

		/// <summary>
		/// Gets or sets the parent TextEditor.
		/// </summary>
		public TextEditor TextEditor
		{
			get
			{
				if (controlReference != null && controlReference.IsAlive)
					return controlReference.Target as TextEditor;
				else
					return null;
			}
			protected set { controlReference = new WeakReference(value); }
		}

		/// <summary>
		/// Gets or sets what ScrollBars should be visible in the SplitViewChildControl.
		/// </summary>
		public ScrollBars ScrollBars
		{
			get { return scrollBars; }
			set
			{
				scrollBars = value;

				// Update all of the ScrollBars to match what the user has just set.

				if (this.ScrollBars == ScrollBars.Both)
				{
					hScroll.Visible = true;
					vScroll.Visible = true;
				}

				if (this.ScrollBars == ScrollBars.None)
				{
					hScroll.Visible = false;
					vScroll.Visible = false;
				}

				if (this.ScrollBars == ScrollBars.Horizontal)
				{
					hScroll.Visible = true;
					vScroll.Visible = false;
				}

				if (this.ScrollBars == ScrollBars.Vertical)
				{
					hScroll.Visible = false;
					vScroll.Visible = true;
				}

				filler.Visible = hScroll.Visible == true && vScroll.Visible == true;

				// Set the thumbs' sizes depending on what ScrollBars are visible.

				if (vScroll.Visible == true && hasThumbs == true)
					this.TopThumb.Height = 8;
				else
					this.TopThumb.Height = 0;

				if (hScroll.Visible == true && hasThumbs == true)
					this.LeftThumb.Width = 8;
				else
					this.LeftThumb.Width = 0;

				// Update the thumbs by calling DoResize and then refreshing the Control.

				this.DoResize();
				this.Refresh();
			}
		}

        /// <summary>
        /// Gets the horizontal ScrollBar.
        /// </summary>
        public DevExpress.XtraEditors.HScrollBar HScrollBar {
            get { return hScroll; }
        }

        /// <summary>
        /// Gets the vertical ScrollBar.
        /// </summary>
        public DevExpress.XtraEditors.VScrollBar VScrollBar {
            get { return vScroll; }
        }

		#endregion

		#region Methods

		#region Private

		private void OnScrollVisibleChanged(object sender, EventArgs e)
		{
			// Update the child Controls of the SplitViewChildControl's Visible property
			// to match whether what ScrollBars are visible.

			filler.Visible = hScroll.Visible == true || vScroll.Visible == true;

			this.LeftThumb.Visible = this.LeftThumbVisible == true && hScroll.Visible == true;
			this.TopThumb.Visible  = this.TopThumbVisible  == true && vScroll.Visible == true;
		}

		/// <summary>
		/// Updates the sizes and visibility of the SplitViewChildControl's child Controls,
		/// including the left and top SplitViewThumbControl and the ScrollBars.
		/// </summary>
		private void DoResize()
		{
			this.SuspendLayout();
			if (this.TopThumb == null)
				return;

            this.TopThumb.Width = SystemInformation.VerticalScrollBarWidth;
            this.LeftThumb.Height = SystemInformation.HorizontalScrollBarHeight;

            vScroll.Width = SystemInformation.VerticalScrollBarWidth;
            hScroll.Height = SystemInformation.HorizontalScrollBarHeight;

            if (this.TopThumbVisible == true) {
                vScroll.Top = this.TopThumb.Height;
                vScroll.Height = this.ClientHeight - hScroll.Height - this.TopThumb.Height;
            }
            else {
                vScroll.Height = this.ClientHeight - hScroll.Height;
                vScroll.Top = 0;
            }

            if (this.LeftThumbVisible == true) {
                hScroll.Left = this.LeftThumb.Width;
                hScroll.Width = this.ClientWidth - vScroll.Width - this.LeftThumb.Width;
            }
            else {
                hScroll.Width = this.ClientWidth - vScroll.Width;
                hScroll.Left = 0;
            }

            vScroll.Left = this.ClientWidth - vScroll.Width;
            hScroll.Top = this.ClientHeight - hScroll.Height;

            this.LeftThumb.Left = 0;
            this.LeftThumb.Top = hScroll.Top;

            this.TopThumb.Left = vScroll.Left;
            this.TopThumb.Top = 0;

            filler.Left = vScroll.Left;
            filler.Top = hScroll.Top;
            filler.Width = vScroll.Width;
            filler.Height = hScroll.Height;

            vScroll.Bounds = Rectangle.FromLTRB(vScroll.Left, vScroll.Top, vScroll.Right, filler.Top);
            hScroll.Bounds = Rectangle.FromLTRB(hScroll.Left, hScroll.Top, filler.Left, hScroll.Bottom);
            filler.BringToFront();

			this.ResumeLayout(false);
		}

		#endregion

		#region Protected

		protected override void Dispose(bool disposing)
		{
			if (disposing)
			{
				if (components != null)
				{
					components.Dispose();
				}
			}

			base.Dispose(disposing);
		}

		protected override void OnResize(EventArgs e)
		{
			// Call the DoResize method to update sizes of the child Controls
			// in the SplitViewChildControl.

			this.DoResize();
			base.OnResize(e);
		}

		#endregion

		#region Public

		/// <summary>
		/// Hides the top and left SplitViewThumbControls.
		/// </summary>
		public void HideThumbs()
		{
			this.TopThumb.Height = 0;
			this.LeftThumb.Width = 0;

			hasThumbs = false;
			this.DoResize();
		}

		/// <summary>
		/// Shows the top and left SplitViewThumbControls.
		/// </summary>
		public void ShowThumbs()
		{
			this.TopThumb.Height = 8;
			this.LeftThumb.Width = 8;

			hasThumbs = true;
			this.DoResize();
		}

		#endregion

		#endregion

		/// <summary>
		/// Initializes a new instance of SplitViewChildControl.
		/// </summary>
		public SplitViewChildControl(TextEditor parent)
		{
			this.TextEditor = parent;

			// Required by the Windows Forms Designer.
			InitializeComponent();

			hScroll.VisibleChanged += OnScrollVisibleChanged;
			vScroll.VisibleChanged += OnScrollVisibleChanged;
		}

		#region Component Designer generated code

		private void InitializeComponent()
		{
			System.Resources.ResourceManager resources = new System.Resources.ResourceManager(typeof(SplitViewChildControl));
            hScroll = new DevExpress.XtraEditors.HScrollBar();
            vScroll = new DevExpress.XtraEditors.VScrollBar();
			filler = new System.Windows.Forms.Panel();
			TopThumb = new SplitViewThumbControl();
			LeftThumb = new SplitViewThumbControl();


			SuspendLayout();
			// 
			// hScroll
			// 
			hScroll.Location = new System.Drawing.Point(-4, 292);
			hScroll.Name = "hScroll";
			hScroll.Size = new System.Drawing.Size(440, 16);
			hScroll.TabIndex = 0;

			// 
			// vScroll
			// 
			vScroll.Location = new System.Drawing.Point(440, 0);
			vScroll.Maximum = 300;
			vScroll.Minimum = 0;
			vScroll.Name = "vScroll";
			vScroll.Size = new System.Drawing.Size(16, 360);
			vScroll.TabIndex = 1;
			// 
			// Filler
			// 
			filler.BackColor = System.Drawing.SystemColors.Control;
			filler.Location = new System.Drawing.Point(64, 260);
			filler.Name = "Filler";
			filler.Size = new System.Drawing.Size(20, 20);
			filler.TabIndex = 3;
			// 
			// TopThumb
			// 
			TopThumb.BackColor = System.Drawing.SystemColors.Control;
			TopThumb.Cursor = System.Windows.Forms.Cursors.HSplit;
			TopThumb.Location = new System.Drawing.Point(101, 17);
			TopThumb.Name = "TopThumb";
			TopThumb.Size = new System.Drawing.Size(16, 8);
			TopThumb.TabIndex = 3;
			TopThumb.Visible = false;
			// 
			// LeftThumb
			// 
			LeftThumb.BackColor = System.Drawing.SystemColors.Control;
			LeftThumb.Cursor = System.Windows.Forms.Cursors.VSplit;
			LeftThumb.Location = new System.Drawing.Point(423, 17);
			LeftThumb.Name = "LeftThumb";
			LeftThumb.Size = new System.Drawing.Size(8, 16);
			LeftThumb.TabIndex = 3;
			LeftThumb.Visible = false;

			// 
			// SplitViewChildControl
			// 
			Controls.AddRange(new System.Windows.Forms.Control[]
				{
					TopThumb,
					LeftThumb,
					filler,
					vScroll,
					hScroll
				});
			Name = "SplitViewChildControl";
			Size = new System.Drawing.Size(456, 376);
			ResumeLayout(false);
		}

		#endregion
	}
}
